package com.wxapp.gateway.web.filter;

import com.wxapp.common.base.util.jackson.JacksonUtil;
import com.wxapp.common.constant.constant.LoginConstant;
import com.wxapp.common.constant.enums.ResultEnum;
import com.wxapp.common.constant.pojo.vm.ResultVm;
import com.wxapp.gateway.web.util.CheckUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Objects;


/**
 * @author lgl
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered {
    private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);

    private final CheckUtil checkUtil;

    public AuthFilter(CheckUtil checkUtil) {
        this.checkUtil = checkUtil;
    }
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        log.info("{}  请求接口:{}", LocalDateTime.now(), request.getURI().getPath());
        // 是否合法url
        String token = request.getHeaders().getFirst(LoginConstant.TOKEN_KEY);
        //判断权限
        var anEnum = checkUtil.havePermission(request,token);
        if (anEnum.getValue() !=200) {
            return responseError(exchange, anEnum);
        }
        return toNext(exchange, request, chain, token);
    }

    /**
     * 跳转下一步
     */
    private Mono<Void> toNext(ServerWebExchange exchange, ServerHttpRequest request, GatewayFilterChain chain, String token) {
        if (token == null || token.isEmpty()) {
            return chain.filter(exchange);
        }
        var mutate = exchange.getRequest().mutate();
        mutate.header(LoginConstant.INTERNAL_TOKEN_KEY, token);
        mutate.header(LoginConstant.CLIENT, request.getHeaders().getFirst(LoginConstant.CLIENT));
        mutate.build();
        var build = mutate.build();
        exchange = exchange.mutate().request(build).build();
        return chain.filter(exchange);
    }

    /**
     * 错误返回值
     */
    private Mono<Void> responseError(ServerWebExchange exchange, ResultEnum resultEnum) {
        log.info("{}  请求出错{}:{}", LocalDateTime.now(), resultEnum.getValue(),resultEnum.getDesc());
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().set("Content-type", "application/json;charset=UTF-8");
        var wrap = response.bufferFactory().wrap(Objects.requireNonNull(JacksonUtil.toJSONString(new ResultVm<>(resultEnum.getValue(), resultEnum.getDesc(), ""))).getBytes(StandardCharsets.UTF_8));
        return response.writeWith(Flux.just(wrap));
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
